package com.cmd.user;

import java.net.InetSocketAddress;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.mgr.DriverOrderMgr;
import com.mgr.UserOrderMgr;
import com.mgr.UserPayMgr;
import com.player.DriverUser;
import com.player.User;
import com.player.WorldMgr;
import com.qy.bean.OrderDriver;
import com.qy.bean.OrderInfo;
import com.qy.bean.PayInfo;
import com.qy.util.StaticData;
import com.qy.util.TimeUtil;
import com.util.AbstractCommand;
import com.util.PBMessage;
import com.util.QinYiWXPay;

/**
 * 
 * 取消订单
 * 
 * @author zwl 2018年2月1日
 */
public class OrderCancelCMD extends AbstractCommand {

    @Override
    public void execute(User user, PBMessage packet) throws Exception {
	/*
	 * 1.如果是还未接单，则直接取消，
	 * 2.如果是有人接单了或者是接了单还没到达，
	 *   距离用户取车两小时外扣除金额的5%
	 *   距离用户取车两小时内扣除金额的10%
	 *   取消司机的服务号
	 *   取消订单
	 *   取消支付订单
	 *   退款
	 */
	JSONObject reJs = new JSONObject();
	reJs.put(StaticData.reKey.cmd.getKey(),packet.getCode());
	JSONObject param = packet.getMessage();
	if (!param.containsKey("orderId")) {
	    reJs.put(StaticData.reKey.code.getKey(),
		    StaticData.codeType.param_error.getType());
	    user.sendPacket(reJs);
	    return;
	}
	// 订单号
	int orderId = param.getInteger("orderId");
	OrderInfo info = UserOrderMgr.getOrderInfo(orderId);
	if (info == null
		|| info.getOrderStatus() != StaticData.OrderStatus.PAY_NOT_ACCEPT
			.getType()
		|| info.getOrderStatus() != StaticData.OrderStatus.ACCEPT_NOT_ARRIVE
			.getType()
		|| info.getOrderStatus() != StaticData.OrderStatus.ARRIVE_NOT_CHECK
			.getType()) {
	    reJs.put(StaticData.reKey.code.getKey(),
		    StaticData.codeType.ORDER_not_exist.getType());
	    user.sendPacket(reJs);
	    return;
	}
	PayInfo payInfo = UserPayMgr.getPay(info.getPayId());
	if (payInfo == null
		|| payInfo.getPayStatus() != StaticData.PayInfoStatus.FINISH
			.getType()) {
	    reJs.put(StaticData.reKey.code.getKey(),
		    StaticData.codeType.PAY_not_exist.getType());
	    user.sendPacket(reJs);
	    return;
	}
	/*
	 * 判断用户订单状态 如果对应状态取消订单需要扣除一定费用
	 */
	int reduce = 0;
	QinYiWXPay qyp = null;
	OrderDriver od = null;
	if (info.getOrderStatus() != StaticData.OrderStatus.ACCEPT_NOT_ARRIVE.getType()
	|| info.getOrderStatus() != StaticData.OrderStatus.ARRIVE_NOT_CHECK.getType()) {
	    od = DriverOrderMgr.getDriverOrder(info.getFDriver());
	    if (od == null) {
		reJs.put(StaticData.reKey.code.getKey(),StaticData.codeType.ORDER_not_exist.getType());
		user.sendPacket(reJs);
		return;
	    }
	/*
	* 司机端增加对应的费用 
	* 向腾讯请求取消订单
	*/
	    DriverUser driverUser = null;
	    synchronized (this) {
		driverUser = (DriverUser) WorldMgr.getGamePlayer(od.getDriverId(),
			StaticData.userType.DRIVER_USER.getType());
		if (driverUser == null) {
		    reJs.put(StaticData.reKey.code.getKey(),StaticData.codeType.user_not_exist.getType());
		    user.sendPacket(reJs);
		    return;
		}
		/*
		 * 两小时以内扣5% 两小时以外扣10%
		 */
		if (TimeUtil.getSysteCurTime().before(
			TimeUtil.addHourToCurTime(info.getFetchDate(), -2).getTime())) {
		    reduce = payInfo.getOrderPrice() * 5 / 100;
		} else {
		    reduce = payInfo.getOrderPrice() * 10 / 100;
		}
		
		if (reduce > 0) {
		    driverUser.getDriverInfo().setMoney(driverUser.getDriverInfo().getMoney() + reduce);
		}
	    }
	    qyp = new QinYiWXPay(payInfo.getOrderPrice(),
		    ((InetSocketAddress) user.getUserChannel().remoteAddress()).getAddress().getHostAddress(),
		    user.getOpenId(),
		    payInfo.getOrderNum());
	    /*
	     * 服务号取消
	     */
	    od.setStatus(StaticData.DriverOrderStatus.END.getType());
	    driverUser.setServerOrder(null);
	    JSONObject dReJs = new JSONObject();
	    dReJs.put(StaticData.reKey.code.getKey(),StaticData.codeType.ORDER_CANCEL.getType());
	    dReJs.put(StaticData.reKey.cmd.getKey(), 1002);
	    driverUser.sendPacket(dReJs);
	}
	/*
	 * 退款
	 */
	    qyp = new QinYiWXPay(payInfo.getOrderPrice(),
		    ((InetSocketAddress) user.getUserChannel().remoteAddress()).getAddress().getHostAddress(), 
		    user.getOpenId(),
		    payInfo.getOrderNum());
	
	Map<String, String> payParam = qyp.doRefund((payInfo.getOrderPrice() - reduce) + "");
	if (payParam.get("return_code").equals("FAIL")) {
	    reJs.put(StaticData.reKey.code.getKey(),StaticData.codeType.CANCEL_ERROR.getType());
	    reJs.put("err_msg", payParam.get("err_msg"));
	    user.sendPacket(reJs);
	    return;
	}
	if (payParam.get("return_code").equals("FAIL")) {
	    reJs.put(StaticData.reKey.code.getKey(), StaticData.codeType.CANCEL_ERROR.getType());
	    reJs.put("err_msg", payParam.get("err_msg"));
	    user.sendPacket(reJs);
	    return;
	}
	payInfo.setPayStatus(StaticData.PayInfoStatus.REFUND.getType());
	UserPayMgr.update(payInfo);
	info.setOrderStatus(StaticData.OrderStatus.CANCEL.getType());
	UserOrderMgr.update(info);

	reJs.put(StaticData.reKey.code.getKey(),StaticData.codeType.ok.getType());
	reJs.put(StaticData.reKey.cmd.getKey(),packet.getCode());
	user.sendPacket(reJs);
	return;
    }

}
